package com.file.parser;


import com.file.bo.AppAlipayIdCard;
import com.file.bo.AppAlipayPersonal;
import com.file.bo.AppAlipayWsd;
import com.file.bo.ResponseData;
import com.file.constant.ErrorCode;
import com.file.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentException;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 支付宝微商贷xml解析
 * @author anyspa
 */


@Slf4j
public class AppAlipayWsdXmlParser extends AppAlipayBaseXmlParser {

    public ResponseData<String> parseAppAlipayWsdXmlToJson(String daId, String filePath, List<String> wsdNoDataScenarioList) {
        log.info("parseAppAlipayWsdXmlToJson started, daId:{}, filePath:{}", daId, filePath);
        String json = null;

        try {
            if (filePath.contains("alipay_wsd")) {
                AppAlipayWsd appAlipayWsd = parseAppAlipayWsdXml(daId, filePath, wsdNoDataScenarioList);
                json = JsonUtils.convertObjectToJson(appAlipayWsd);
            } else if (filePath.contains("alipay_personal")) {
                AppAlipayPersonal appAlipayPersonal = parseAppAlipayPersonalXml(filePath);
                json = JsonUtils.convertObjectToJson(appAlipayPersonal);
            } else if (filePath.contains("alipay_idcard")) {
                AppAlipayIdCard appAlipayIdCard = parseAppAlipayIdcardXml(filePath);
                json = JsonUtils.convertObjectToJson(appAlipayIdCard);
            } else {
                throw new RuntimeException("the file name is not supported");
            }
        } catch (Exception e) {
            log.error("|{}||{}|{}|{}|{}", ErrorCode.FILE_PARSE_EXCEPTION.getCode(), daId, "", "", "parseAppAlipayWsdXmlToJson failed", e);
            return new ResponseData<>(null, ErrorCode.FILE_PARSE_EXCEPTION.getCode(),
                    ErrorCode.FILE_PARSE_EXCEPTION.getMsg());
        }

        log.info("parseAppAlipayWsdXmlToJson completed, daId:{}, filePath:{}", daId, filePath);
        return new ResponseData<>(json, ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    private AppAlipayWsd processNoDataCase(String wsdNoDataKeyword) {
        AppAlipayWsd appAlipayWsd = new AppAlipayWsd();
        appAlipayWsd.setCaseDesc(wsdNoDataKeyword);
        return appAlipayWsd;
    }

    private AppAlipayWsd processOverDueCase(List<String> nodeTextList) {
        AppAlipayWsd appAlipayWsd = new AppAlipayWsd();
        for (String nodeText : nodeTextList) {
            // 个人贷款全部应还总金额(元)
            // 10,794.05
            // 匹配第一个金额
            Pattern pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*)(.[0-9]{2})");
            Matcher matcher = pattern.matcher(nodeText.trim());
            if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getOverdueAmt())) {
                appAlipayWsd.setOverdueAmt(matcher.group());
                break;
            }
        }

        appAlipayWsd.setCaseDesc("有贷款忘还了");
        return appAlipayWsd;
    }

    private AppAlipayWsd processNormalCase(List<String> nodeTextList) {
        AppAlipayWsd appAlipayWsd = new AppAlipayWsd();
        List<String> annualInterestRateList = new ArrayList<>();
        boolean isArrivedBorrowableAmount = false;
        boolean isArrivedTotalAmount = false;
        int annualInterestRateCase = 0; // text="年利率"
        //正常case里有一种占绝大比例的的有数据case
        for (String nodeText : nodeTextList) {
            if (StringUtils.isNotBlank(nodeText)) {
                if (nodeText.contains("你可以借") || nodeText.contains("预计可借(元)") || nodeText.contains("额度已用完")) {
                    isArrivedBorrowableAmount = true;
                }

                if (isArrivedBorrowableAmount) {
                    // 可借额度 40,000
                    Pattern pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*(?!\\.))|额度已用完");
                    Matcher matcher = pattern.matcher(nodeText.trim());
                    if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getBorrowableAmount())) {
                        if (matcher.group().equals("额度已用完")) {
                            if (StringUtils.isBlank(appAlipayWsd.getBorrowableAmount())) {
                                appAlipayWsd.setBorrowableAmount("0");
                                appAlipayWsd.setCaseDesc("额度已用完");
                            }
                        } else {
                            if (StringUtils.isBlank(appAlipayWsd.getBorrowableAmount())) {
                                appAlipayWsd.setBorrowableAmount(matcher.group());
                            }
                        }
                        continue;
                    }

                    // 总额度 40,000.00
                    if (nodeText.contains("总额度")  && !nodeText.contains("%|")) {
                        isArrivedTotalAmount = true;
                        pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*)(.[0-9]{2})?");
                        matcher = pattern.matcher(nodeText.trim());
                        if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getTotalAmount())) {
                            appAlipayWsd.setTotalAmount(matcher.group());
                        }
                        continue;
                    }

                    if (isArrivedTotalAmount && StringUtils.isBlank(appAlipayWsd.getTotalAmount())) {
                        pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*)(.[0-9]{2})?");
                        matcher = pattern.matcher(nodeText.trim());
                        if (matcher.find()) {
                            appAlipayWsd.setTotalAmount(matcher.group());
                        }
                    }

                    // 年利率12.6%（借1千用1天仅0.35元） ||  年利率12.6%
                    if (nodeText.trim().contains("年利率") && nodeText.trim().length() > 3) {
                        // 年利率12.6%
                        if (nodeText.trim().matches( "年利率" + "\\s?([0-9]{1,2}(.[0-9]{1,3})?%)")) { //NOSONAR
                            annualInterestRateCase = 1;
                            Pattern compile = Pattern.compile("([0-9]{1,2}(.[0-9]{1,3})?%)");
                            Matcher matcher1 = compile.matcher(nodeText.trim());
                            if (matcher1.find()) {
                                annualInterestRateList.add(matcher1.group());
                                continue;
                            }
                        }

                        Pattern compile2 = Pattern.compile("年利率" + "\\s*([0-9]{1,2}(.[0-9]{1,3})?%)\\s*（\\S");
                        Matcher matcher2 = compile2.matcher(nodeText.trim());
                        if (matcher2.find()) {
                            annualInterestRateCase = 2;
                            compile2 = Pattern.compile("([0-9]{1,2}(.[0-9]{1,3})?%)");
                            matcher2 = compile2.matcher(nodeText.trim());
                            if (matcher2.find()) {
                                annualInterestRateList.add(matcher2.group());
                            }
                        }
                        continue;
                    }

                    // 年利率可能没有小数, 可能有1、2、3位小数,  12.775%
                    if (annualInterestRateCase == 0 && nodeText.trim().matches("([0-9]{1,2}(.[0-9]{1,3})?%)")) {
                        if (annualInterestRateList.size() < 2) { //NOSONAR
                            annualInterestRateList.add(nodeText.trim());
                        }
                    }
                }
            }
        }

        if (annualInterestRateList.isEmpty()) {
//            throw new RuntimeException("annual interest rate is empty");
        } else if (annualInterestRateList.size() == 1) {
            appAlipayWsd.setOriginalAnnualInterestRate(annualInterestRateList.get(0));
        } else if (annualInterestRateList.size() == 2) {
            String firstRate = annualInterestRateList.get(0).substring(0, annualInterestRateList.get(0).indexOf("%"));
            String secondRate = annualInterestRateList.get(1).substring(0, annualInterestRateList.get(1).indexOf("%"));
            BigDecimal firstRateBigDecimal = new BigDecimal(firstRate);
            BigDecimal secondRateBigDecimal = new BigDecimal(secondRate);
            if (firstRateBigDecimal.compareTo(secondRateBigDecimal) > 0) {
                appAlipayWsd.setOriginalAnnualInterestRate(annualInterestRateList.get(0));
                appAlipayWsd.setPreferentialAnnualInterestRate(annualInterestRateList.get(1));
            } else {
                appAlipayWsd.setOriginalAnnualInterestRate(annualInterestRateList.get(1));
                appAlipayWsd.setPreferentialAnnualInterestRate(annualInterestRateList.get(0));
            }
        }

        if (StringUtils.isAnyBlank(appAlipayWsd.getBorrowableAmount())) {
            throw new RuntimeException("the parsed field has empty value");
        }

        return appAlipayWsd;
    }

    private AppAlipayWsd parseAppAlipayWsdXml(String daId, String filePath, List<String> wsdNoDataScenarioList) throws DocumentException {
        AppAlipayWsd appAlipayWsd = null;
        List<String> nodeTextList = getNodeTextList(filePath);
        String wsdNoDataKeyword = getNoDataKeyWord(nodeTextList, wsdNoDataScenarioList);

        // 聚合额度
        if (isAggregateCase(nodeTextList)) {
            appAlipayWsd = processAggregateCase(nodeTextList);
        // 有数据的正常页面，走正常设值逻辑
        } else if (isNormalCase(nodeTextList)) {
            appAlipayWsd = processNormalCase(nodeTextList);
        // 涨额度
        } else if (isIncreaseAmountCase(nodeTextList)) {
            appAlipayWsd = processIncreaseAmountCase(nodeTextList);
        // 有数据的逾期案例，走逾期设值逻辑
        } else if (isOverdue(nodeTextList)) {
            appAlipayWsd = processOverDueCase(nodeTextList);
        // 处理体验额度案例,走体验额度设值逻辑
        } else if (isExperienceQuota(nodeTextList)) {
            appAlipayWsd = processExperienceQuotaCase(nodeTextList);
        // 命中无数据关键字配置，走无数据设值逻辑
        } else if (StringUtils.isNotBlank(wsdNoDataKeyword)) {
            appAlipayWsd = processNoDataCase(wsdNoDataKeyword);
        // 有利率无额度 - 订单贷款 · 短期周转
        } else if (isOnlyHasAnnualInterestRateCase(nodeTextList)) {
            appAlipayWsd = processOnlyHasAnnualInterestRateCase(nodeTextList);
        // 有额度无利率 - 放弃优惠，去借钱
        } else if (isOnlyHasTotalAmountAndBorrowableAmountCase(nodeTextList)) {
            appAlipayWsd = processOnlyHasTotalAmountAndBorrowableAmountCase(nodeTextList);
        // 有房有额度（有预估值）
        } else if (isHasHouseCase(nodeTextList)) {
            appAlipayWsd = processHasHouseCase(nodeTextList);
        // 一些非正常页面，将已知case逐个在这里适配
        } else {
            throw new RuntimeException("wsd xml meet new case");
        }

        return appAlipayWsd;
    }

    private boolean isOverdue(List<String> nodeTextList) {
        for (String nodeText : nodeTextList) {
            if (nodeText.contains("有贷款忘还了")) {
                return true;
            }
        }
        return false;
    }

    //xml原文件同时包含可用额度视为正常case (年利率和总额度都可以为空)
    private boolean isNormalCase(List<String> nodeTextList) {
        boolean hasBorrowableAmount = false;
//        boolean hasAnnualInterestRate = false;

        for (String nodeText : nodeTextList) {
            if (nodeText.contains("你可以借") || nodeText.contains("预计可借(元)") || nodeText.contains("额度已用完")) {
                hasBorrowableAmount = true;
            }
//            if (nodeText.contains("年利率")) {
//            if (matchKeyWord(nodeText, cccsService.getWsd_annualInterestRateKeyWordList())) {
//                hasAnnualInterestRate = true;
//            }
        }
        return hasBorrowableAmount;
    }

    private boolean isExperienceQuota(List<String> nodeTextList) {
        for (String nodeText : nodeTextList) {
            if (nodeText.contains("你有体验额度可借")) {
                return true;
            }
        }
        return false;
    }

    private AppAlipayWsd processExperienceQuotaCase(List<String> nodeTextList) {
        AppAlipayWsd appAlipayWsd = new AppAlipayWsd();
        //正常case里有一种占绝大比例的的有数据case
        for (String nodeText : nodeTextList) {
            if (StringUtils.isNotBlank(nodeText)) {

                // 你有体验额度可借 500
                // Pattern pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*(?!\\.))");
                Pattern pattern = Pattern.compile("([0-9]{2,3}(,[0-9]{3})*(?!\\.))");
                Matcher matcher = pattern.matcher(nodeText.trim());
                if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getBorrowableAmount())) {
                    appAlipayWsd.setBorrowableAmount(matcher.group());
                    continue;
                }

                // 年利率可能没有小数, 可能有1、2、3位小数,  12.775%
                if (nodeText.trim().matches("年利率(\\(单利\\))?([0-9]{1,2}(.[0-9]{1,3})?%)") && StringUtils.isBlank(appAlipayWsd.getOriginalAnnualInterestRate())) {
                    String annualInterestRate = nodeText.trim().substring(3);
                    if (nodeText.contains("年利率(单利)")) {
                        annualInterestRate = nodeText.trim().substring(7);
                    }
                    appAlipayWsd.setOriginalAnnualInterestRate(annualInterestRate);
                }
            }
        }

        // 体验额度可能没有利率
        if (StringUtils.isAnyBlank(appAlipayWsd.getBorrowableAmount())) {
            throw new RuntimeException("the parsed field has empty value");
        }
        appAlipayWsd.setCaseDesc("体验额度");
        return appAlipayWsd;
    }

    //xml原文件同时包含"同意协议涨额度"视为涨额度case
    private boolean isIncreaseAmountCase(List<String> nodeTextList) {
        for (String nodeText : nodeTextList) {
            if (nodeText.contains("同意协议涨额度")) {
                return true;
            }
        }
        return false;
    }

    private boolean isAggregateCase(List<String> nodeTextList) {
        boolean hasBorrowableText = false;
        boolean hasAggregateInfo = false;
        // 年利率12.6%|总额度66,150元
//        String regex = "年利率([0-9]{1,2}(.[0-9]{1,3})?%)\\|总额度([0-9]{1,3}(,[0-9]{3})*(?!\\.))元";
        String regex = "年利率(\\(单利\\))?([0-9]{1,2}(.[0-9]{1,3})?%)\\|总额度([0-9]{1,3}(,[0-9]{3})*(?!\\.))元";
        for (String nodeText : nodeTextList) {
            if (nodeText.contains("可借额度") || nodeText.contains("预计可借(元)")) {
                hasBorrowableText = true;
            }
            if (nodeText.trim().matches(regex)) {
                hasAggregateInfo = true;
            }
        }
        return hasBorrowableText && hasAggregateInfo;
    }

    private boolean isOnlyHasAnnualInterestRateCase(List<String> nodeTextList) {
        for (String nodeText : nodeTextList) {
            if (nodeText.contains("订单贷款 · 短期周转") || (nodeText.contains("订单贷款") && nodeText.contains("短期周转"))) {
                return true;
            }
        }
        return false;
    }

    private boolean isOnlyHasTotalAmountAndBorrowableAmountCase(List<String> nodeTextList) {
        for (String nodeText : nodeTextList) {
            if (nodeText.contains("放弃优惠，去借钱")) {
                return true;
            }
        }
        return false;
    }

    private boolean isHasHouseCase(List<String> nodeTextList) {
        boolean hasHouse = false;
        boolean hasEstimate = false;
        for (String nodeText : nodeTextList) {
            if (nodeText.contains("有房有额度")) {
                hasHouse = true;
            } else if (nodeText.contains("预估")) {
                hasEstimate = true;
            }
        }
        return hasHouse && hasEstimate;
    }

    private AppAlipayWsd processAggregateCase(List<String> nodeTextList) {
        boolean isProcessPureAggregateCase = true;
        for (String nodeText : nodeTextList) {
            if (StringUtils.contains(nodeText.trim(), "总额度临时提升至")) {
                isProcessPureAggregateCase = false;
                break;
            }
        }

        if (isProcessPureAggregateCase) {
            return processPureAggregateCase(nodeTextList);
        } else {
            return processAggregateAndTemporaryAmountCase(nodeTextList);
        }
    }

    // 聚合额度: 纯聚合额度
    private AppAlipayWsd processPureAggregateCase(List<String> nodeTextList) {
        AppAlipayWsd appAlipayWsd = new AppAlipayWsd();
        List<AppAlipayWsd.AggregateInfo> aggregateInfoList = new ArrayList<>();
        // 默认两家贷款机构
        AppAlipayWsd.AggregateInfo aggregateInfo1 = null;
        AppAlipayWsd.AggregateInfo aggregateInfo2 = null;
        boolean isArrivedBorrowableAmount = false;
        boolean isArrivedFirstAggregateInfo = false;
        boolean isFirstAggregateInfoComplete = false;

        for (String nodeText : nodeTextList) {
            if (StringUtils.isNotBlank(nodeText)) {
                if (nodeText.contains("可借额度") || nodeText.contains("预计可借(元)")) {
                    isArrivedBorrowableAmount = true;
                }

                if (isArrivedBorrowableAmount) {
                    // 可借额度174,122元
                    Pattern pattern = Pattern.compile("([0-9]{0,3}(,[0-9]{3})*(?!\\.))|额度已用完");
                    Matcher matcher = pattern.matcher(nodeText.trim());
                    if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getBorrowableAmount())) {
                        if (matcher.group().equals("额度已用完")) {
                            appAlipayWsd.setBorrowableAmount("0");
                        } else {
                            appAlipayWsd.setBorrowableAmount(matcher.group());
                        }
                        continue;
                    }

                    // 654,680
                    // pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*(?!\\.))");
                    // matcher = pattern.matcher(nodeText.trim());
                    // if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getTotalAmount())) {
                    //     appAlipayWsd.setTotalAmount(matcher.group());
                    //     continue;
                    // }

                    if (!isFirstAggregateInfoComplete) {
                        // 第一个聚合额度
                        // 正常情况下, 贷款机构在前面
                        if (StringUtils.containsAny(nodeText, "银行", "农商行")) {
                            isArrivedFirstAggregateInfo = true;
                            if (aggregateInfo1 == null) {
                                aggregateInfo1 = new AppAlipayWsd.AggregateInfo();
                            }
                            if (StringUtils.isBlank(aggregateInfo1.getLenders())) {
                                aggregateInfo1.setLenders(nodeText.trim());
                                continue;
                            }
                        }

                        pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*(?!\\.))|额度已用完");
                        matcher = pattern.matcher(nodeText.trim());
                        if (matcher.find()) {
                            if (aggregateInfo1 == null) {
                                aggregateInfo1 = new AppAlipayWsd.AggregateInfo();
                            }
                            if (isArrivedFirstAggregateInfo && StringUtils.isBlank(aggregateInfo1.getBorrowableAmount())) {
                                if (matcher.group().equals("额度已用完")) {
                                    aggregateInfo1.setBorrowableAmount("0");
                                } else {
                                    aggregateInfo1.setBorrowableAmount(matcher.group());
                                }
                                continue;
                            }
                        }

                        pattern = Pattern.compile("年利率(\\(单利\\))?([0-9]{1,2}(.[0-9]{1,3})?%)\\|总额度([0-9]{1,3}(,[0-9]{3})*(?!\\.))元");
                        matcher = pattern.matcher(nodeText.trim());
                        if (matcher.find()) {
                            if (aggregateInfo1 == null) {
                                aggregateInfo1 = new AppAlipayWsd.AggregateInfo();
                            }
                            if (StringUtils.isBlank(aggregateInfo1.getTotalAmount())) {
                                String text = matcher.group();
                                if (text.contains("年利率(单利)")) {
                                    aggregateInfo1.setAnnualInterestRate(text.substring(text.indexOf("年利率(单利)") + 7, text.indexOf("|总额度")));
                                } else {
                                    aggregateInfo1.setAnnualInterestRate(text.substring(text.indexOf("年利率") + 3, text.indexOf("|总额度")));
                                }
                                aggregateInfo1.setTotalAmount(text.substring(text.indexOf("总额度") + 3, text.indexOf("元")));
                                isFirstAggregateInfoComplete = true;
                            }
                        }
                    } else {
                        // 第二个聚合额度
                        if (StringUtils.containsAny(nodeText, "银行", "农商行")) {
                            if (aggregateInfo2 == null) {
                                aggregateInfo2 = new AppAlipayWsd.AggregateInfo();
                            }
                            if (StringUtils.isBlank(aggregateInfo2.getLenders())) {
                                aggregateInfo2.setLenders(nodeText.trim());
                                continue;
                            }
                        }

                        pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*(?!\\.))|额度已用完");
                        matcher = pattern.matcher(nodeText.trim());
                        if (matcher.find()) {
                            if (aggregateInfo2 == null) {
                                aggregateInfo2 = new AppAlipayWsd.AggregateInfo();
                            }
                            if (StringUtils.isBlank(aggregateInfo2.getBorrowableAmount())) {
                                if (matcher.group().equals("额度已用完")) {
                                    aggregateInfo2.setBorrowableAmount("0");
                                } else {
                                    aggregateInfo2.setBorrowableAmount(matcher.group());
                                }
                                continue;
                            }
                        }

                        pattern = Pattern.compile("年利率(\\(单利\\))?([0-9]{1,2}(.[0-9]{1,3})?%)\\|总额度([0-9]{1,3}(,[0-9]{3})*(?!\\.))元");
                        matcher = pattern.matcher(nodeText.trim());
                        if (matcher.find()) {
                            if (aggregateInfo2 == null) {
                                aggregateInfo2 = new AppAlipayWsd.AggregateInfo();
                            }
                            if (StringUtils.isBlank(aggregateInfo2.getTotalAmount())) {
                                String text = matcher.group();
                                if (text.contains("年利率(单利)")) {
                                    aggregateInfo2.setAnnualInterestRate(text.substring(text.indexOf("年利率(单利)") + 7, text.indexOf("|总额度")));
                                } else {
                                    aggregateInfo2.setAnnualInterestRate(text.substring(text.indexOf("年利率") + 3, text.indexOf("|总额度")));
                                }
                                aggregateInfo2.setTotalAmount(text.substring(text.indexOf("总额度") + 3, text.indexOf("元")));
                            }
                        }
                    }
                }
            }
        }
        if (aggregateInfo1 != null) {
            aggregateInfoList.add(aggregateInfo1);
        }
        if (aggregateInfo2 != null) {
            aggregateInfoList.add(aggregateInfo2);
        }

        if (aggregateInfoList.isEmpty()) {
            throw new RuntimeException("aggregate info list is empty");
        }
        appAlipayWsd.setCaseDesc(JsonUtils.convertObjectToJson(aggregateInfoList));
        return appAlipayWsd;
    }

    // 聚合额度: 临时额度+聚合额度
    private AppAlipayWsd processAggregateAndTemporaryAmountCase(List<String> nodeTextList) {
        AppAlipayWsd appAlipayWsd = new AppAlipayWsd();
        List<AppAlipayWsd.AggregateInfo> aggregateInfoList = new ArrayList<>();
        // 默认两家贷款机构
        AppAlipayWsd.AggregateInfo aggregateInfo1 = null;
        AppAlipayWsd.AggregateInfo aggregateInfo2 = null;
        boolean isArrivedBorrowableAmount = false;
        boolean hasTemporaryAmount = false;
        boolean isFirstAggregateInfoComplete = false;
        for (String nodeText : nodeTextList) {
            if (StringUtils.isNotBlank(nodeText)) {
                if (nodeText.contains("可借额度") || nodeText.contains("预计可借(元)")) {
                    isArrivedBorrowableAmount = true;
                } else if (nodeText.contains("总额度临时提升至")) {
                    hasTemporaryAmount = true;
                } else if (StringUtils.contains(nodeText, "补充银行流水户均涨")) {
                    continue;
                }

                if (isArrivedBorrowableAmount) {
                    // 可借额度174,122元
                    Pattern pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*(?!\\.))|额度已用完");
                    Matcher matcher = pattern.matcher(nodeText.trim());
                    if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getBorrowableAmount())) {
                        if (matcher.group().equals("额度已用完")) {
                            appAlipayWsd.setBorrowableAmount("0");
                        } else {
                            appAlipayWsd.setBorrowableAmount(matcher.group());
                        }
                        continue;
                    }

                    if (hasTemporaryAmount) {
                        // 654,680
                        pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*(?!\\.))");
                        matcher = pattern.matcher(nodeText.trim());
                        if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getTotalAmount())) {
                            appAlipayWsd.setTotalAmount(matcher.group());
                            continue;
                        }

                        if (!isFirstAggregateInfoComplete) {
                            // 第一个聚合额度
                            // 正常情况下, 贷款机构在前面
                            if (StringUtils.containsAny(nodeText, "银行", "农商行")) {
                                if (aggregateInfo1 == null) {
                                    aggregateInfo1 = new AppAlipayWsd.AggregateInfo();
                                }
                                if (StringUtils.isBlank(aggregateInfo1.getLenders())) {
                                    aggregateInfo1.setLenders(nodeText.trim());
                                    continue;
                                }
                            }

                            pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*(?!\\.))|额度已用完");
                            matcher = pattern.matcher(nodeText.trim());
                            if (matcher.find()) {
                                if (aggregateInfo1 == null) {
                                    aggregateInfo1 = new AppAlipayWsd.AggregateInfo();
                                }
                                if (StringUtils.isBlank(aggregateInfo1.getBorrowableAmount())) {
                                    if (matcher.group().equals("额度已用完")) {
                                        aggregateInfo1.setBorrowableAmount("0");
                                    } else {
                                        aggregateInfo1.setBorrowableAmount(matcher.group());
                                    }
                                    continue;
                                }
                            }

                            pattern = Pattern.compile("年利率(\\(单利\\))?([0-9]{1,2}(.[0-9]{1,3})?%)\\|总额度([0-9]{1,3}(,[0-9]{3})*(?!\\.))元");
                            matcher = pattern.matcher(nodeText.trim());
                            if (matcher.find()) {
                                if (aggregateInfo1 == null) {
                                    aggregateInfo1 = new AppAlipayWsd.AggregateInfo();
                                }
                                if (StringUtils.isBlank(aggregateInfo1.getTotalAmount())) {
                                    String text = matcher.group();
                                    if (text.contains("年利率(单利)")) {
                                        aggregateInfo1.setAnnualInterestRate(text.substring(text.indexOf("年利率(单利)") + 7, text.indexOf("|总额度")));
                                    } else {
                                        aggregateInfo1.setAnnualInterestRate(text.substring(text.indexOf("年利率") + 3, text.indexOf("|总额度")));
                                    }
                                    aggregateInfo1.setTotalAmount(text.substring(text.indexOf("总额度") + 3, text.indexOf("元")));
                                    isFirstAggregateInfoComplete = true;
                                }
                            }
                        } else {
                            // 第二个聚合额度
                            if (StringUtils.containsAny(nodeText, "银行", "农商行")) {
                                if (aggregateInfo2 == null) {
                                    aggregateInfo2 = new AppAlipayWsd.AggregateInfo();
                                }
                                if (StringUtils.isBlank(aggregateInfo2.getLenders())) {
                                    aggregateInfo2.setLenders(nodeText.trim());
                                    continue;
                                }
                            }

                            pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*(?!\\.))|额度已用完");
                            matcher = pattern.matcher(nodeText.trim());
                            if (matcher.find()) {
                                if (aggregateInfo2 == null) {
                                    aggregateInfo2 = new AppAlipayWsd.AggregateInfo();
                                }
                                if (StringUtils.isBlank(aggregateInfo2.getBorrowableAmount())) {
                                    if (matcher.group().equals("额度已用完")) {
                                        aggregateInfo2.setBorrowableAmount("0");
                                    } else {
                                        aggregateInfo2.setBorrowableAmount(matcher.group());
                                    }
                                    continue;
                                }
                            }

                            pattern = Pattern.compile("年利率(\\(单利\\))?([0-9]{1,2}(.[0-9]{1,3})?%)\\|总额度([0-9]{1,3}(,[0-9]{3})*(?!\\.))元");
                            matcher = pattern.matcher(nodeText.trim());
                            if (matcher.find()) {
                                if (aggregateInfo2 == null) {
                                    aggregateInfo2 = new AppAlipayWsd.AggregateInfo();
                                }
                                if (StringUtils.isBlank(aggregateInfo2.getTotalAmount())) {
                                    String text = matcher.group();
                                    if (text.contains("年利率(单利)")) {
                                        aggregateInfo2.setAnnualInterestRate(text.substring(text.indexOf("年利率(单利)") + 7, text.indexOf("|总额度")));
                                    } else {
                                        aggregateInfo2.setAnnualInterestRate(text.substring(text.indexOf("年利率") + 3, text.indexOf("|总额度")));
                                    }
                                    aggregateInfo2.setTotalAmount(text.substring(text.indexOf("总额度") + 3, text.indexOf("元")));
                                }
                            }
                        }
                    }
                }
            }
        }
        if (aggregateInfo1 != null) {
            aggregateInfoList.add(aggregateInfo1);
        }
        if (aggregateInfo2 != null) {
            aggregateInfoList.add(aggregateInfo2);
        }

        if (aggregateInfoList.isEmpty()) {
            throw new RuntimeException("aggregate info list is empty");
        }
        appAlipayWsd.setCaseDesc(JsonUtils.convertObjectToJson(aggregateInfoList));
        return appAlipayWsd;
    }

    private AppAlipayWsd processIncreaseAmountCase(List<String> nodeTextList) {
        AppAlipayWsd appAlipayWsd = new AppAlipayWsd();
        boolean isArrivedBorrowableAmount = false;
        for (String nodeText : nodeTextList) {
            if (StringUtils.isNotBlank(nodeText)) {
                if (nodeText.contains("当前额度")) {
                    isArrivedBorrowableAmount = true;
                }

                if (isArrivedBorrowableAmount) {
                    // 1,000
                    Pattern pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*(?!\\.))");
                    Matcher matcher = pattern.matcher(nodeText.trim());
                    if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getBorrowableAmount())) {
                        appAlipayWsd.setBorrowableAmount(matcher.group());
                        continue;
                    }

                    // 年利率17.64%（借1千用1天仅0.49元）
                    if (nodeText.trim().contains("年利率") && nodeText.trim().length() > 3) {  //NOSONAR
                        // 年利率17.64%
                        if (nodeText.trim().matches("年利率(\\(单利\\))?\\s?([0-9]{1,2}(.[0-9]{1,3})?%\\S*)")) {  //NOSONAR
                            pattern = Pattern.compile("([0-9]{1,2}(.[0-9]{1,3})?%)");
                            matcher = pattern.matcher(nodeText.trim());
                            if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getOriginalAnnualInterestRate())) {
                                appAlipayWsd.setOriginalAnnualInterestRate(matcher.group());
                            }
                        }
                    }
                }
            }
        }

        if (StringUtils.isAnyBlank(appAlipayWsd.getBorrowableAmount())) {
            throw new RuntimeException("the parsed field has empty value");
        }
        appAlipayWsd.setCaseDesc("同意协议涨额度");
        return appAlipayWsd;
    }

    private AppAlipayWsd processOnlyHasAnnualInterestRateCase(List<String> nodeTextList) {
        AppAlipayWsd appAlipayWsd = new AppAlipayWsd();
        Pattern pattern = Pattern.compile("([0-9]{1,2}(.[0-9]{1,3})?%)");
        for (String nodeText : nodeTextList) {
            // 年利率16%
            if (nodeText.trim().contains("年利率") && nodeText.trim().length() > 3) {
                // 年利率16%
                if (nodeText.trim().matches("年利率(\\(单利\\))?\\s?([0-9]{1,2}(.[0-9]{1,3})?%\\S*)")) {//NOSONAR
                    Matcher matcher = pattern.matcher(nodeText.trim());
                    if (matcher.find()) {
                        appAlipayWsd.setOriginalAnnualInterestRate(matcher.group());
                        appAlipayWsd.setCaseDesc("订单贷款·短期周转");
                        return appAlipayWsd;
                    }
                }
            }
        }
        throw new RuntimeException("processOnlyHasAnnualInterestRateCase fail.");
    }

    private AppAlipayWsd processOnlyHasTotalAmountAndBorrowableAmountCase(List<String> nodeTextList) {
        AppAlipayWsd appAlipayWsd = new AppAlipayWsd();
        boolean isArrivedBorrowableAmount = false;
        for (int i = 0; i < nodeTextList.size(); i++) {
            String nodeText = nodeTextList.get(i);
            if (StringUtils.isNotBlank(nodeText)) {
                if (nodeText.contains("你可以借")) {
                    isArrivedBorrowableAmount = true;
                }

                if (isArrivedBorrowableAmount) {
                    // 可借额度 40,000
                    Pattern pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*(?!\\.))|额度已用完");
                    Matcher matcher = pattern.matcher(nodeText.trim());
                    if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getBorrowableAmount())) {
                        if (matcher.group().equals("额度已用完")) {
                            appAlipayWsd.setBorrowableAmount("0");
                            appAlipayWsd.setCaseDesc("额度已用完");
                        } else {
                            appAlipayWsd.setBorrowableAmount(matcher.group());
                        }
                        continue;
                    }

                    // 总额度 40,000.00
                    if (nodeText.contains("总额度")) {
                        pattern = Pattern.compile("([0-9]{1,3}(,[0-9]{3})*)(.[0-9]{2})?");
                        matcher = pattern.matcher(nodeText.trim());
                        if (matcher.find() && StringUtils.isBlank(appAlipayWsd.getTotalAmount())) {
                            appAlipayWsd.setTotalAmount(matcher.group());
                        }
                        continue;
                    }

                    // 日利率
                    // 0.0375%
                    // (借1千用1天仅0.38元)
                    Pattern compile = Pattern.compile("(0.[0-9]{2,5})%");
                    Matcher matcher1 = compile.matcher(nodeText.trim());
                    if (matcher1.find()) {
                        if (nodeText.contains("日利率")) {
                            appAlipayWsd.setCaseDesc(matcher1.group());
                        } else {
                            appAlipayWsd.setCaseDesc("日利率" + matcher1.group() + nodeTextList.get(i + 1));
                        }
                        return appAlipayWsd;
                    }
                }
            }
        }

        throw new RuntimeException("processOnlyHasTotalAmountAndBorrowableAmountCase fail.");
    }

    private AppAlipayWsd processHasHouseCase(List<String> nodeTextList) {
        AppAlipayWsd appAlipayWsd = new AppAlipayWsd();
        boolean isArrivedHasHouse = false;
        for (String nodeText : nodeTextList) {
            // 有房有额度
            if (nodeText.trim().contains("有房有额度")) {
                isArrivedHasHouse = true;
                continue;
            }

            if (isArrivedHasHouse) {
                // 预估
                // 160
                // 万
                Pattern pattern = Pattern.compile("([0-9]{1,5})");
                Matcher matcher = pattern.matcher(nodeText.trim());
                if (matcher.find()) {
                    if (nodeText.contains("预估")) {
                        appAlipayWsd.setCaseDesc("有房有额度, " + matcher.group());
                    } else {
                        appAlipayWsd.setCaseDesc("有房有额度, 预估" +  matcher.group() + "万");
                    }
                    return appAlipayWsd;
                }
            }
        }
        throw new RuntimeException("processHasHouseCase fail.");
    }

    public static void main(String[] args) {
        AppAlipayWsdXmlParser appAlipayWsdXmlParser = new AppAlipayWsdXmlParser();
        List<String> wsdNoDataScenarioList = Arrays.asList("暂时无法为你提供服务", "无可用额度", "暂未确认你的经营身份", "暂时没有贷款额度", "网商贷借钱已关闭", "本次申请未通过");
        String json = appAlipayWsdXmlParser.parseAppAlipayWsdXmlToJson("", "C:\\Users\\lingfeng\\Downloads\\zd4pkdq81787871445692801024_507db806732a99139aa15a5be6b405a4_alipay_wsd.xml", wsdNoDataScenarioList).getData();
        System.out.println(json);

    }
}